package com.example.learning;

public class Learning2 {

    /**
     * 对多个线程访问同一资源添加synchronized锁
     * synchronized 关键字确保在同一时间内，只有一个线程可以执行 method() 方法。
     * 当 thread1 获取到 method() 方法的锁时，即使 thread1 在方法内调用了 Thread.sleep()，锁依然被 thread1 占用，其他线程（比如 thread2）无法进入该方法。
     */
    /**
     * synchronized 的使用是为了对 run() 方法中使用的共享资源 进行加锁，防止多个线程在同一时间对这些共享资源进行并发访问，导致数据竞争（Race Condition） 或 数据不一致 的问题。
     */
    public synchronized void method() {
        int i = 0;
        while (i < 10) {
            try {
                /**
                 * Thread.sleep() 的作用是让当前线程暂时让出 CPU 执行权，但线程在 sleep 状态下，不会释放对象锁。
                 * 即使 thread1 进入休眠状态，其他线程（如 thread2）仍然无法获取到 method() 的锁，除非 thread1 执行完 method() 方法或抛出异常导致锁释放。
                 */
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("Hello World" + i++);
            System.out.println(Thread.currentThread().getName());
        }
    }

    /**
     * 当你创建一个线程对象时，线程是“新建”状态（NEW）。
     * 调用 start() 方法后，线程进入“就绪”状态（RUNNABLE）。
     * 当线程被 CPU 调度器（Scheduler）调度后，线程开始执行 run() 方法，进入“运行”状态（RUNNING）。
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        Learning2 learning2 = new Learning2();

        /**
         * 匿名内部类
         */
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                learning2.method();
            }
        });

        /**
         * Lambda表达式
         */
        Thread thread1 = new Thread(() -> learning2.method());
        Thread thread2 = new Thread(() -> learning2.method());

        thread1.setName("first one:");
        thread2.setName("second tow:");

        thread1.start();
        thread2.start();

        System.out.println(thread1.getName() + ":" + thread1.getState());
        System.out.println(thread2.getName() + ":" + thread2.getState());

        /**
         * 在 Java 中，Thread.sleep() 是一个静态方法，它的作用是让当前线程（即调用 sleep() 方法的线程）进入休眠状态。
         * Thread.sleep() 并不会影响其他线程的状态。
         * sleep() 只会暂停当前线程的执行。
         * 如果 sleep() 是在 main 方法中调用的，那么被暂停的就是main 线程。
         */
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName());

        thread1.join();
        thread2.join();

        System.out.println(thread1.getName() + ":" + thread1.getState());
        System.out.println(thread2.getName() + ":" + thread2.getState());

    }
}
